/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxDefaultToolbarCodec
 *
 * Custom codec for configuring <mxDefaultToolbar>s. This class is created
 * and registered dynamically at load time and used implicitely via
 * <mxCodec> and the <mxCodecRegistry>. This codec only reads configuration
 * data for existing toolbars handlers, it does not encode or create toolbars.
 */
var mxDefaultToolbarCodec = mxCodecRegistry.register(function()
{
    var codec = new mxObjectCodec(new mxDefaultToolbar());

    /**
     * Function: encode
     *
     * Returns null.
     */
    codec.encode = function(enc, obj)
    {
        return null;
    };

    /**
     * Function: decode
     *
     * Reads a sequence of the following child nodes
     * and attributes:
     *
     * Child Nodes:
     *
     * add - Adds a new item to the toolbar. See below for attributes.
     * separator - Adds a vertical separator. No attributes.
     * hr - Adds a horizontal separator. No attributes.
     * br - Adds a linefeed. No attributes.
     *
     * Attributes:
     *
     * as - Resource key for the label.
     * action - Name of the action to execute in enclosing editor.
     * mode - Modename (see below).
     * template - Template name for cell insertion.
     * style - Optional style to override the template style.
     * icon - Icon (relative/absolute URL).
     * pressedIcon - Optional icon for pressed state (relative/absolute URL).
     * id - Optional ID to be used for the created DOM element.
     * toggle - Optional 0 or 1 to disable toggling of the element. Default is
     * 1 (true).
     *
     * The action, mode and template attributes are mutually exclusive. The
     * style can only be used with the template attribute. The add node may
     * contain another sequence of add nodes with as and action attributes
     * to create a combo box in the toolbar. If the icon is specified then
     * a list of the child node is expected to have its template attribute
     * set and the action is ignored instead.
     *
     * Nodes with a specified template may define a function to be used for
     * inserting the cloned template into the graph. Here is an example of such
     * a node:
     *
     * (code)
     * <add as="Swimlane" template="swimlane" icon="images/swimlane.gif"><![CDATA[
     *   function (editor, cell, evt, targetCell)
     *   {
     *     var pt = mxUtils.convertPoint(
     *       editor.graph.container, mxEvent.getClientX(evt),
     *         mxEvent.getClientY(evt));
     *     return editor.addVertex(targetCell, cell, pt.x, pt.y);
     *   }
     * ]]></add>
     * (end)
     *
     * In the above function, editor is the enclosing <mxEditor> instance, cell
     * is the clone of the template, evt is the mouse event that represents the
     * drop and targetCell is the cell under the mousepointer where the drop
     * occurred. The targetCell is retrieved using <mxGraph.getCellAt>.
     *
     * Futhermore, nodes with the mode attribute may define a function to
     * be executed upon selection of the respective toolbar icon. In the
     * example below, the default edge style is set when this specific
     * connect-mode is activated:
     *
     * (code)
     * <add as="connect" mode="connect"><![CDATA[
     *   function (editor)
     *   {
     *     if (editor.defaultEdge != null)
     *     {
     *       editor.defaultEdge.style = 'straightEdge';
     *     }
     *   }
     * ]]></add>
     * (end)
     *
     * Both functions require <mxDefaultToolbarCodec.allowEval> to be set to true.
     *
     * Modes:
     *
     * select - Left mouse button used for rubberband- & cell-selection.
     * connect - Allows connecting vertices by inserting new edges.
     * pan - Disables selection and switches to panning on the left button.
     *
     * Example:
     *
     * To add items to the toolbar:
     *
     * (code)
     * <mxDefaultToolbar as="toolbar">
     *   <add as="save" action="save" icon="images/save.gif"/>
     *   <br/><hr/>
     *   <add as="select" mode="select" icon="images/select.gif"/>
     *   <add as="connect" mode="connect" icon="images/connect.gif"/>
     * </mxDefaultToolbar>
     * (end)
     */
    codec.decode = function(dec, node, into)
    {
        if (into != null)
        {
            var editor = into.editor;
            node = node.firstChild;

            while (node != null)
            {
                if (node.nodeType == mxConstants.NODETYPE_ELEMENT)
                {
                    if (!this.processInclude(dec, node, into))
                    {
                        if (node.nodeName == 'separator')
                        {
                            into.addSeparator();
                        }
                        else if (node.nodeName == 'br')
                        {
                            into.toolbar.addBreak();
                        }
                        else if (node.nodeName == 'hr')
                        {
                            into.toolbar.addLine();
                        }
                        else if (node.nodeName == 'add')
                        {
                            var as = node.getAttribute('as');
                            as = mxResources.get(as) || as;
                            var icon = node.getAttribute('icon');
                            var pressedIcon = node.getAttribute('pressedIcon');
                            var action = node.getAttribute('action');
                            var mode = node.getAttribute('mode');
                            var template = node.getAttribute('template');
                            var toggle = node.getAttribute('toggle') != '0';
                            var text = mxUtils.getTextContent(node);
                            var elt = null;

                            if (action != null)
                            {
                                elt = into.addItem(as, icon, action, pressedIcon);
                            }
                            else if (mode != null)
                            {
                                var funct = (mxDefaultToolbarCodec.allowEval) ? mxUtils.eval(text) : null;
                                elt = into.addMode(as, icon, mode, pressedIcon, funct);
                            }
                            else if (template != null || (text != null && text.length > 0))
                            {
                                var cell = editor.templates[template];
                                var style = node.getAttribute('style');

                                if (cell != null && style != null)
                                {
                                    cell = editor.graph.cloneCell(cell);
                                    cell.setStyle(style);
                                }

                                var insertFunction = null;

                                if (text != null && text.length > 0 && mxDefaultToolbarCodec.allowEval)
                                {
                                    insertFunction = mxUtils.eval(text);
                                }

                                elt = into.addPrototype(as, icon, cell, pressedIcon, insertFunction, toggle);
                            }
                            else
                            {
                                var children = mxUtils.getChildNodes(node);

                                if (children.length > 0)
                                {
                                    if (icon == null)
                                    {
                                        var combo = into.addActionCombo(as);

                                        for (var i=0; i<children.length; i++)
                                        {
                                            var child = children[i];

                                            if (child.nodeName == 'separator')
                                            {
                                                into.addOption(combo, '---');
                                            }
                                            else if (child.nodeName == 'add')
                                            {
                                                var lab = child.getAttribute('as');
                                                var act = child.getAttribute('action');
                                                into.addActionOption(combo, lab, act);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        var select = null;
                                        var create = function()
                                        {
                                            var template = editor.templates[select.value];

                                            if (template != null)
                                            {
                                                var clone = template.clone();
                                                var style = select.options[select.selectedIndex].cellStyle;

                                                if (style != null)
                                                {
                                                    clone.setStyle(style);
                                                }

                                                return clone;
                                            }
                                            else
                                            {
                                                mxLog.warn('Template '+template+' not found');
                                            }

                                            return null;
                                        };

                                        var img = into.addPrototype(as, icon, create, null, null, toggle);
                                        select = into.addCombo();

                                        // Selects the toolbar icon if a selection change
                                        // is made in the corresponding combobox.
                                        mxEvent.addListener(select, 'change', function()
                                        {
                                            into.toolbar.selectMode(img, function(evt)
                                            {
                                                var pt = mxUtils.convertPoint(editor.graph.container,
                                                    mxEvent.getClientX(evt), mxEvent.getClientY(evt));

                                                return editor.addVertex(null, funct(), pt.x, pt.y);
                                            });

                                            into.toolbar.noReset = false;
                                        });

                                        // Adds the entries to the combobox
                                        for (var i=0; i<children.length; i++)
                                        {
                                            var child = children[i];

                                            if (child.nodeName == 'separator')
                                            {
                                                into.addOption(select, '---');
                                            }
                                            else if (child.nodeName == 'add')
                                            {
                                                var lab = child.getAttribute('as');
                                                var tmp = child.getAttribute('template');
                                                var option = into.addOption(select, lab, tmp || template);
                                                option.cellStyle = child.getAttribute('style');
                                            }
                                        }

                                    }
                                }
                            }

                            // Assigns an ID to the created element to access it later.
                            if (elt != null)
                            {
                                var id = node.getAttribute('id');

                                if (id != null && id.length > 0)
                                {
                                    elt.setAttribute('id', id);
                                }
                            }
                        }
                    }
                }

                node = node.nextSibling;
            }
        }

        return into;
    };

    // Returns the codec into the registry
    return codec;

}());

/**
 * Variable: allowEval
 *
 * Static global switch that specifies if the use of eval is allowed for
 * evaluating text content. Default is true. Set this to false if stylesheets
 * may contain user input
 */
mxDefaultToolbarCodec.allowEval = true;
